using System;
using System.Collections.Generic;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;

namespace Utils
{
    public class FrameRateCounter : DrawableGameComponent
    {
        private SpriteBatch m_kSpriteBatch;
        private SpriteFont m_kFont;

        private Vector2 m_vPosition;

		//private float m_fCurrentFrameRate;

        const int m_iQueueFrameCount = 1000;
        private Queue<float> m_kLastFrames = new Queue<float>();
        
        public FrameRateCounter(Game game, Vector2 vPosition)
            : base(game)
        {
            m_vPosition = vPosition;

            // Make this draw over the asteroids and ship.
            DrawOrder = 1000;
        }

        protected override void LoadContent()
        {
            IGraphicsDeviceService graphicsService = (IGraphicsDeviceService)this.Game.Services.GetService(typeof(IGraphicsDeviceService));

            m_kSpriteBatch = new SpriteBatch(graphicsService.GraphicsDevice);
            m_kFont = Game.Content.Load<SpriteFont>("fpsfont");

            base.LoadContent();
        }
        
        protected override void UnloadContent()
        {
            base.UnloadContent();
        }
        
        public override void Update(GameTime gameTime)
        {
            m_kLastFrames.Enqueue(1 / (float) gameTime.ElapsedGameTime.TotalSeconds);

            if (m_kLastFrames.Count > m_iQueueFrameCount)
                m_kLastFrames.Dequeue();

			base.Update(gameTime);
        }
        
        public override void Draw(GameTime gameTime)
        {
            m_kSpriteBatch.Begin();

            // Calculate average.
            float fFPSAverage;
            float total = 0.0f;
            foreach (float i in m_kLastFrames)
            {
                total += i;
            }
            fFPSAverage = total / m_kLastFrames.Count;

            // Find highest frame
            float highestFPS = m_kLastFrames.Peek();
            foreach (float i in m_kLastFrames)
            {
                if (i > highestFPS) highestFPS = i;
            }

            // Find lowest frame
            float lowestFPS = m_kLastFrames.Peek();
            foreach (float i in m_kLastFrames)
            {
                if (i < lowestFPS) lowestFPS = i;
            }

            // Color this based on the framerate
            Color DrawColor = Color.Green;
            if (fFPSAverage < 15.0f)
                DrawColor = Color.Red;
            else if (fFPSAverage < 30.0f)
                DrawColor = Color.Yellow;

          //  m_kSpriteBatch.DrawString(m_kFont, "FPS: " + fFPSAverage.ToString("f3") + "\nHighest: " + highestFPS.ToString("f3") + "\nLowest: " + lowestFPS.ToString("f3"), m_vPosition, DrawColor);
            m_kSpriteBatch.End();
            base.Draw(gameTime);
        }

		public void ResetFPSCount()
		{
            m_kLastFrames.Clear();
		}
    }
}
